/**
 * Universita' degli Studi di Palermo, 2010-11, License GNU GPL 3 (http://www.gnu.org/licenses/gpl.html)
 */
package org.unipa.botplatform.bot;

import java.io.IOException;
import java.net.URL;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;



/**
 * A BotParser parses the bot configuration file.
 * <br> <br>
 * The bot configuration file (typically <code>bots.xml</code>) contains the bots that the Core must 
 * instantiate, with the reference beans used in any instance.
 * @author Giuseppe Miceli
 *
 */
public class BotParser{

	private static SAXBuilder builder = new SAXBuilder(true);

	/**
	 * The <code>parse</code> method takes the URL of the file to parse, and a default 
	 * BotContext object indicating default values for the parser. It returns a map containing all the bots 
	 * (the bot name is used as key) with their corresponding context.
	 * @param botsURL URL path to the bots definition file.
	 * @param defaultBotContext Default BotContext to use with missing beans in bot definition.
	 * @return
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	static public Map<String, BotContext> parse(URL botsURL, String botsSchema, URL botsSchemaURL, BotContext defaultBotContext) throws JDOMException, IOException{	

		builder.setFeature(
				"http://apache.org/xml/features/validation/schema", true);
		builder.setProperty(
				"http://apache.org/xml/properties/schema/external-schemaLocation",
				botsSchema + " " + botsSchemaURL.toExternalForm());

		Document document;
		try {
			document = builder.build(botsURL);
		} catch (JDOMException e) {
			e.printStackTrace();
			throw new JDOMException(
					"Error during bots configuration file parsing. Please check bots file (" + botsURL.toExternalForm() +
					") and its schema (" + botsSchemaURL.toExternalForm() + ")");
		} catch (IOException e) {
			e.printStackTrace();
			throw new IOException(
					"Error during bots configuration file reading. Please check bots file existance (" + botsURL.toExternalForm() + ")");
		}

		Element rootElement = document.getRootElement();
		@SuppressWarnings("unchecked")
		List<Element> bots = rootElement.getChildren();

		Map<String, BotContext> map = new HashMap<String, BotContext>(bots.size());

		for(Element bot:bots){
			Namespace ns = bot.getNamespace();
			String name = bot.getAttribute("name").getValue();

			String botBean = bot.getChild("botType", ns) != null ? bot.getChildTextTrim("botType", ns) : defaultBotContext.getBotBean();

			String plannerBean = bot.getChild("plannerType", ns) != null ? bot.getChildTextTrim("plannerType", ns) : defaultBotContext.getPlannerBean();

			String sessionBean = bot.getChild("sessionType", ns) != null ? bot.getChildTextTrim("sessionType", ns) : defaultBotContext.getSessionBean();

			BotContext botContext = new BotContext();
			botContext.setBotBean(botBean);
			botContext.setPlannerBean(plannerBean);
			botContext.setSessionBean(sessionBean);

			map.put(name, botContext);
		}
		return map;
	}
}
